// 异步写日志的日志队列
// 需要涉及到线程安全
#pragma once
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
//模板代码的实现只能写在头文件当中
template <typename T>
class LockQueue
{
public:
    //对于push，多个工作线程都会调用写日志
    void push(const T &data)
    {
        std::lock_guard<std::mutex> lock(m_mutex);//使用类似只能指针的锁，自动的加锁和释放锁，加完东西后出函数后就自动释放锁
        m_queue.push(data);
        m_condvariable.notify_one();//写入数据后唤醒磁盘i\o线程
    }
    //对于pop只有一个线程从队列读日志文件，并且向磁盘中写入日志文件
    T pop()
    {
        std::unique_lock<std::mutex> lock(m_mutex);//条件变量需要的
        while(m_queue.empty())//使用while防止线程的虚假唤醒
        {
            //如果日志队列为空，那么就不让它去抢锁的资源了，因为抢到了也没用，直接让它等待就好了,并且释放锁
            m_condvariable.wait(lock);
        }
        T data=m_queue.front();
        m_queue.pop();
        return data;
    }

private:
    std::queue<T> m_queue;
    std::mutex m_mutex;
    std::condition_variable m_condvariable;
};